package com.dys.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @Author: 疾风
 * @ClassName: LogAspect
 * @Description: 切面类
 * @CreateDate: 2024/10/21
 * @Version: v1.0.0
 */
@Aspect // 被该注解所修饰的Java类就是一个切面类
// @Component // 注册为spring容器的一个Bean组件
public class LogAspect {

    /**
     * 前置通知
     *
     * @param joinPoint 连接点：可以被选择来进行增强的方法点
     */
    @Before(value = "execution(public int com.dys.service.impl.CalculatorImpl.*(..))")
    public void beforeMethod(JoinPoint joinPoint) {
        System.out.println("前置通知执行了-----beforeMethod-----");
        String name = joinPoint.getSignature().getName();
        String args = Arrays.toString(joinPoint.getArgs());
        System.out.println("执行前置通知方法的相关信息：" + name + "()的方法,传递的形式参数是：" + args);
    }

    /**
     * 后置通知:可以获取目标方法的返回结果
     *
     * @param joinPoint 连接点
     * @param res       映射
     */
    @AfterReturning(value = "execution(* com.dys.service.impl.*.*(..))", returning = "res")
    public void afterReturningMethod(JoinPoint joinPoint, Object res) {
        String name = joinPoint.getSignature().getName();
        System.out.println("后置通知--AfterReturning--执行: " + name + "()的方法,返回结果：" + res);
    }

    /**
     * 环绕通知
     *
     * @param joinPoint 连接点
     * @return 环绕通知执行返回结果
     * @throws Throwable 异常
     */
    @Around(value = "execution(* com.dys.service.impl.*.*(..))")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        Object obj = null;
        try {
            System.out.println("环绕通知--Around--执行之前......");
            // 执行目标对象的方法
            obj = joinPoint.proceed();
            System.out.println("环绕通知--Around--执行之后......");
        } catch (Throwable e) {
            e.printStackTrace();
            System.err.println("环绕通知--Around--执行异常");
        } finally {
            System.out.println("环绕通知--Around--最终执行完成end");
        }
        return obj;
    }

    /**
     * 异常通知
     *
     * @param joinPoint 连接点
     * @param ex        异常对象
     */
    @AfterThrowing(value = "execution(* com.dys.service.impl.*.*(..))", throwing = "ex")
    public void afterThrowingMethod(JoinPoint joinPoint, Throwable ex) {
        String name = joinPoint.getSignature().getName();
        System.out.println("异常通知--AfterThrowing--执行：" + name + "()方法,出现了：" + ex + "异常");
    }

    /**
     * 最终通知
     *
     * @param joinPoint 连接点
     */
    @After(value = "execution(* com.dys.service.impl.*.*(..))")
    public void afterMethod(JoinPoint joinPoint) {
        String name = joinPoint.getSignature().getName();
        System.out.println("最终通知--After--执行了：" + name + "方法");
    }
}
